﻿using FastColoredTextBoxNS;
using System.Collections.Generic;
using System.Text.RegularExpressions;


namespace MPE
{
    static class ToolTips
    {
        static Dictionary<string, int> break_points = new Dictionary<string, int>();
        static Dictionary<string, int> go_to_break_points = new Dictionary<string, int>();
        static Dictionary<string, List<int>> lines_of_go_to_break_points = new Dictionary<string, List<int>>();
        public static void getToolTip(ref object sender, ref ToolTipNeededEventArgs e)
        {
            Range range = DataHelper.field.GetLine(e.Place.iLine);
            Regex rgx = new Regex(@"\$?[a-zA-Z_]*" + e.HoveredWord + @"[a-zA-Z_\d]*");
            Match mc = rgx.Match(range.Text);
            string hoveredWord = "";
            if (mc.Success) hoveredWord = mc.Value;

            string bp = range.GetFragment("[^\n]").Text;
            Match mch = DataHelper.GO_TO_BREAK_POINT.Match(bp), mch1 = DataHelper.BREAK_POINT.Match(bp);
            if (mch.Success || mch1.Success)
            {
                break_points.Clear(); lines_of_go_to_break_points.Clear(); go_to_break_points.Clear();
                get_all_bp(ref sender);
            }
            bool nextTip = false;
            if (mch.Success)
            {// Навели на параметр функции GO_TO_BREAK_POINT => возвращаем номер строки где объявлена точка возврата
                string str = bp.Remove(0, mch.Value.Length);
                string[] split = str.Split(new char[] { ']' });
                if (split.Length > 0)
                {
                    if (split.Length == 1)
                    {
                        if (break_points.TryGetValue(split[0].Remove(0, 1), out int line))
                            e.ToolTipText = $"Метка возврата обьявлена на {line + 1} строке";

                        else e.ToolTipText = "Не удалось найти обьявление этой метки возврата";
                    }
                    else if (split.Length == 2)
                    {
                        if (break_points.TryGetValue(hoveredWord, out int line))
                            e.ToolTipText = $"Метка возврата обьявлена на {line + 1} строке";

                        nextTip = true;
                    }
                }
                if (!nextTip) return;
            }
            else
            {
                if (mch1.Success && !(e.HoveredWord.Contains("BREAK") || e.HoveredWord.Contains("POINT")))
                {
                    string str = bp.Remove(0, mch1.Length).Remove(0, 1);
                    str = str.Split(new char[] { ']' })[0];
                    if (lines_of_go_to_break_points.TryGetValue(str, out List<int> lines))
                    {
                        string output = "";
                        for (int i = 0; i < lines.Count; i++) output += $"\n   {lines[i]}";
                        e.ToolTipText = $"Метка имеет {lines.Count} вызова на строках {output}";
                    }
                    else e.ToolTipText = "Метка не имеет вызовов";
                    return;
                }
            }
            if (e.HoveredWord.Length == 0) return;

            Match match = Regex.Match(hoveredWord, @"(\[*[A-Z]*.*\]*)+");//Очистка от мусора
            Match indent = DataHelper.currentIndent_rgx.Match(match.Value);
            string clearedHoveredWord = match.Value;
            if (indent.Value.Length > 0) clearedHoveredWord = match.Value.Remove(0, indent.Value.Length);//Удаляем лишнии отступы в начале

            if (match.Success)
            {
                string[] split = clearedHoveredWord.Split(new string[] { "]" }, System.StringSplitOptions.None);
                clearedHoveredWord = split.Length > 1 ? split[0] + "]" : split[0];
            }
            if (clearedHoveredWord.Contains(e.HoveredWord))
            {
                toolTipsValues.TryGetValue(clearedHoveredWord.Replace(" ", ""), out string tooltip);
                if (tooltip != null && tooltip.Length > 0)
                { e.ToolTipTitle = clearedHoveredWord; e.ToolTipText = tooltip; }
                else
                {
                    toolTipsValues.TryGetValue("[" + clearedHoveredWord.Replace(" ", "") + "]", out tooltip);
                    if (tooltip != null && tooltip.Length > 0)
                    { e.ToolTipTitle = clearedHoveredWord; e.ToolTipText = tooltip; }
                }
            }
        }

        public static string getToolTipForItem(string item)
        {
            toolTipsValues.TryGetValue(item, out string tooltip);
            return tooltip != null && tooltip.Length > 0 ? tooltip : "";
        }

        static void get_all_bp(ref object field)
        {
            FastColoredTextBox range = (field as FastColoredTextBox);
            for (int i = 0; i < range.LinesCount; i++)
            {
                Range line = range.GetLine(i);
                Match mch = DataHelper.BREAK_POINT.Match(line.Text);
                if (mch.Success)
                {
                    string str = line.Text.Remove(0, mch.Length);
                    DataHelper.getClearedString(ref str);

                    if (str.Contains("]")) str = str.Remove(str.Length - 1, 1);
                    if (str.Contains("[")) str = str.Remove(0, 1);

                    try { break_points.Add(str, line.ToLine); } catch { }
                }
                else
                {
                    mch = DataHelper.GO_TO_BREAK_POINT.Match(line.Text);
                    if (mch.Success)
                    {
                        string str = line.Text.Remove(0, mch.Length).Remove(0, 1);
                        str = str.Split(new char[] { ']' })[0];
                        if (go_to_break_points.TryGetValue(str, out int value))
                        { go_to_break_points.Remove(str); go_to_break_points.Add(str, value + 1); }
                        else go_to_break_points.Add(str, value + 1);

                        if (lines_of_go_to_break_points.TryGetValue(str, out List<int> li))
                        { li.Add(line.ToLine + 1); lines_of_go_to_break_points[str] = li; }
                        else lines_of_go_to_break_points.Add(str, new List<int> { line.ToLine + 1 });
                    }
                }
            }
        }
        static Dictionary<string, string> toolTipsValues;
    }
}
